package org.lep.leetcode.sumroottoleafnumbers;

import java.util.Stack;

/**
 *
 * Source : https://oj.leetcode.com/problems/sum-root-to-leaf-numbers/
 *
 * Created by lverpeng on 2017/8/24.
 *
 * Given a binary tree containing digits from 0-9 only, each root-to-leaf path could represent a number.
 * An example is the root-to-leaf path 1->2->3 which represents the number 123.
 *
 * Find the total sum of all root-to-leaf numbers.
 *
 * For example,
 *
 *     1
 *    / \
 *   2   3
 *
 * The root-to-leaf path 1->2 represents the number 12.
 * The root-to-leaf path 1->3 represents the number 13.
 *
 * Return the sum = 12 + 13 = 25.
 *
 */
public class SumRootToLeafNumbers {


    /**
     * 求出由根节点到叶子节点组成所有数字的和
     *
     * 可以使用深度优先DFS求出所有的数字然后求和
     * 也可以使用BFS，逐层求和，求和的时候不是直接加该节点的值，是该节点的值加上上一节点的10倍(子节点处表示的数字就是root.value*10 + node.value)
     * 直到最后一个没有子节点的节点的时候，该节点的值就是最后的和
     *
     * 相当于将根节点到叶子节点路径所表示的数字集中到叶子节点上，然后对叶子节点求和
     *
     * @param root
     * @return
     */
    public int sum (TreeNode root) {
        Stack<TreeNode> stack = new Stack<TreeNode>();
        stack.push(root);
        int sum = 0;

        while (stack.size() > 0) {
            TreeNode node = stack.pop();
            if (node.leftChild != null) {
                node.leftChild.value += node.value * 10;
                stack.push(node.leftChild);
            }
            if (node.rightChild != null) {
                node.rightChild.value += node.value * 10;
                stack.push(node.rightChild);
            }
            if (node.leftChild == null && node.rightChild == null) {
                sum += node.value;
            }
        }
        return sum;
    }




    public TreeNode createTree (char[] treeArr) {
        TreeNode[] tree = new TreeNode[treeArr.length];
        for (int i = 0; i < treeArr.length; i++) {
            if (treeArr[i] == '#') {
                tree[i] = null;
                continue;
            }
            tree[i] = new TreeNode(treeArr[i]-'0');
        }
        int pos = 0;
        for (int i = 0; i < treeArr.length && pos < treeArr.length-1; i++) {
            if (tree[i] != null) {
                tree[i].leftChild = tree[++pos];
                if (pos < treeArr.length-1) {
                    tree[i].rightChild = tree[++pos];
                }
            }
        }
        return tree[0];
    }


    private class TreeNode {
        TreeNode leftChild;
        TreeNode rightChild;
        int value;

        public TreeNode(int value) {
            this.value = value;
        }

        public TreeNode() {

        }
    }

    public static void main(String[] args) {
        SumRootToLeafNumbers sumRootToLeafNUmbers = new SumRootToLeafNumbers();
        char[] arr = new char[]{'1','2','3'};
        System.out.println(sumRootToLeafNUmbers.sum(sumRootToLeafNUmbers.createTree(arr)));
    }

}
